/*
**********************************************************************************
    OpenSURF642 : An TI DM642 implementation of OpenSURF.
    Copyright (C) 2011  Hai Yu

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
	This implementation is based on The original OpenSURF library created
	by Christopher Evans.The original work can be found at
		http://www.chrisevansdev.com/computer-vision-opensurf.html
	
    contact: yuhaihai12345@gmail.com	
**********************************************************************************
*/

#ifndef _SURF_CLASS_
#define _SURF_CLASS_
#include "OpenSurf642Util.h"
#include "IPoint.h"
#include "FastHessian.h"


/***********    Definition of constants  ***************************/

#define ORIENTATION_WINDOW_WIDTH  60
#define ORIENTATION_SEARCH_RESOLUTION 4
#define ORIENTATION_BIN_SIZE (360/ORIENTATION_SEARCH_RESOLUTION)

/***********    Definition of structures  ***************************/
typedef struct{
	IntegralImage * image;
	IPoint   *ipts;
	Uint16   ipts_count;
	Uint16   index;

} Surf;


/***********    Declaration of Interfaces  ***************************/

Surf * CreateSurf(IntegralImage * img, IPoint * ipts, Uint16 ipts_count);

void DestroySurf(Surf * surf);

void getDescriptors(Surf * self, Uint8 bUpright);

/***********    Declaration of Internal Functions  *******************/
//! Assign the current Ipoint an orientation
void getOrientation(Surf * self);

//! Get the descriptor. See Agrawal ECCV 08
void getDescriptor(Surf * self, Uint8 bUpright);

//! Calculate the value of the 2d gaussian at x,y
extern const float pi;
inline float gaussian(Uint16 x, Uint16 y, float sig)
{
	return (1.0f/(2.0f*pi*sig*sig)) * exp( -(x*x+y*y)/(2.0f*sig*sig));
}
inline float gaussian2(float x, float y, float sig)
{
	return (1.0f/(2.0f*pi*sig*sig)) * exp( -(x*x+y*y)/(2.0f*sig*sig));
}



//! Calculate Haar wavelet responses in x and y directions
inline int haarX(Surf * self, Uint16 row, Uint16 column, Uint16 s)
{

	return (BoxIntegral(self->image, row-s/2, column, s, s/2) 
    	-1 * BoxIntegral(self->image, row-s/2, column-s/2, s, s/2));
}
inline int haarY(Surf * self, Uint16 row, Uint16 column, Uint16 s)
{
	return (BoxIntegral(self->image, row, column-s/2, s/2, s) 
    	-1 * BoxIntegral(self->image, row-s/2, column-s/2, s/2, s));
}

//! Get the angle from the +ve x-axis of the vector given by [X Y]
float getAngle(float X, float Y);
#endif

